<script lang="ts" name="DeptTree" setup>
import { ref, watch } from 'vue'
import type { LoadFunction } from 'element-plus'
import type { TreeInstance } from 'element-plus'
import { http } from '@/services/request'
import type { NodeClickData, TreeConfig, TreeNode, TreeProps } from './interface'

// Define types for better type safety

interface ComponentProps {
  config?: TreeConfig
  treeProps?: TreeProps
}

// Props with defaults
const props = withDefaults(defineProps<ComponentProps>(), {
  treeProps: () => ({
    label: 'name',
  }),
  config: () => ({
    url: '/',
    method: 'get',
  }),
})

const emits = defineEmits<{
  (e: 'node-click', data: NodeClickData | Record<string, never>): void
}>()

const treeRef = ref<TreeInstance>()
const searchStr = ref<string>('')
const currentNodeKey = ref<number | null>()

const loadNode: LoadFunction = async (node, resolve) => {
  try {
    const res = await http.request<TreeNode[]>({
      url: props.config?.url,
      method: props.config?.method,
      params: {
        parentId: node?.data?.id || null,
        searchKey: searchStr.value,
      },
    })
    resolve(res || [])
  } catch (error) {
    console.error(error)
    resolve([])
  }
}

watch(searchStr, (val) => {
  if (treeRef.value) {
    treeRef.value.filter(val)
  }
})

const filterNode = (value: string, data: TreeNode) => {
  if (!value) return true
  const labelKey = props.treeProps?.label || 'name'
  return String(data[labelKey]).includes(value)
}

const handleNodeClick = (data: NodeClickData) => {
  if (currentNodeKey.value !== data.id) {
    currentNodeKey.value = data.id
    emits('node-click', data)
  } else {
    currentNodeKey.value = null
    emits('node-click', {})
    if (treeRef.value) {
      treeRef.value.setCurrentKey(undefined, false)
    }
  }
}
</script>

<template>
  <div class="flex flex-col h-full">
    <div class="p-2">
      <el-input v-model="searchStr" placeholder="搜索" clearable />
    </div>
    <div class="flex-1" oncontextmenu="self.event.returnValue=false">
      <el-scrollbar wrap-class="scrollbar-wrapper h-full">
        <el-tree
          ref="treeRef"
          :props="treeProps"
          :load="loadNode"
          lazy
          node-key="id"
          :expand-on-click-node="false"
          :highlight-current="true"
          @node-click="handleNodeClick"
          :filter-node-method="filterNode"
        >
          <template #empty>
            <el-empty description="空空如也" />
          </template>
          <template #default="{ node }">
            <div class="flex items-center">
              <div class="flex-1">{{ node.label }}</div>
            </div>
          </template>
        </el-tree>
      </el-scrollbar>
    </div>
  </div>
</template>
